// Copyright (C) 2005-2008 Jae Stutzman (jaebird@gmail.com)
//
// This file is part of Podducer.
//
// Podducer is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Podducer is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Podducer.  If not, see <http://www.gnu.org/licenses/>.

#region Using

using System;
using System.Drawing;
using System.Configuration;
using System.IO;
using System.Windows.Forms;
using System.Xml;

#endregion Using

	/// <summary>
	/// This class contains the overloaded static method GetAppSetting 
	/// for retrieving various types from the xml config file.
	/// </summary>
public class AppConfigure
{
	private AppConfigure()
	{
	}

	public static string GetAppSetting(string key, string DefaultValue)
	{
		string setting = GetAppSetting(key);
		return (setting != string.Empty) ? setting : DefaultValue;
	}

	public static int GetAppSetting(string key, int DefaultValue)
	{
		int AppSetValue = DefaultValue;
		string setting = GetAppSetting(key);

		if (setting != string.Empty)
		{
			try
			{
				AppSetValue = Convert.ToInt32(setting);
			}
			catch(Exception e)
			{
				ExceptionHandling(e, key, DefaultValue.ToString());
			}
		}
		return AppSetValue;
	}

	public static double GetAppSetting(string key, double DefaultValue)
	{
		double AppSetValue = DefaultValue;
		string setting = GetAppSetting(key);

		if (setting != string.Empty)
		{
			try
			{
				AppSetValue = Convert.ToDouble(setting);
			}
			catch(Exception e)
			{
				ExceptionHandling(e, key, DefaultValue.ToString());
			}
		}
		return AppSetValue;
	}

	public static Color GetAppSetting(string key, Color DefaultValue)
	{
		Color AppSetValue = DefaultValue;
		string setting = GetAppSetting(key);

		if (setting != string.Empty)
		{
			//If name is not the valid name of a pre-defined color, the FromName method 
			//creates a Color structure that has an ARGB value of zero.
			AppSetValue = Color.FromName(setting);
		}
		return AppSetValue;
	}

	public static Image GetAppSetting(string key, Image DefaultValue)
	{
		Image AppSetValue = DefaultValue;
		string setting = GetAppSetting(key);

		if (setting != string.Empty)
		{
			try
			{
				AppSetValue = Image.FromFile(Application.StartupPath + Path.DirectorySeparatorChar + setting);
			}
			catch(Exception e)
			{
				ExceptionHandling(e, key, DefaultValue.ToString());
			}
		}
		return AppSetValue;
	}

	public static bool GetAppSetting(string key, bool DefaultValue)
	{
		bool appSetValue = DefaultValue;
		string setting = GetAppSetting(key);

		if (setting != string.Empty)
		{
			try
			{
				appSetValue = Convert.ToBoolean(setting);
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message);
			}
		}

		return appSetValue;
	}

	public static string GetAppSetting(string settingKey)
	{
		try
		{
			XmlDocument doc = new XmlDocument();
			doc.PreserveWhitespace = true;
			
			// setup the path...
			String configFilename = Application.ExecutablePath + ".config";

			// load the xml config file...
			doc.Load(configFilename);

			XmlNodeList appSettingsList = doc.GetElementsByTagName("appSettings");
			//XmlNode appSettingsNode = appSettingsList.Item(0);

			XmlNodeList nodeList = doc.GetElementsByTagName("add");

			// searching to see if the "key" already exists...
			foreach (XmlNode node in nodeList)
			{
				if (node.Attributes[0].Value == settingKey)
				{
					return node.Attributes[1].Value;
				}
			}
		}
		catch{}

		return string.Empty;
	}

	public static bool SetAppSetting(string settingKey, string settingValue)
	{
		return UpdateConfigSetting(settingKey, settingValue);
	}

	public static bool SetAppSetting(string settingKey, int settingValue)
	{
		string settingStringValue = settingValue.ToString();

		return UpdateConfigSetting(settingKey, settingStringValue);
	}

	public static bool SetAppSetting(string settingKey, double settingValue)
	{
		string settingStringValue = settingValue.ToString();

		return UpdateConfigSetting(settingKey, settingStringValue);
	}

	public static bool SetAppSetting(string settingKey, bool settingValue)
	{
		string settingStringValue = settingValue.ToString();

		return UpdateConfigSetting(settingKey, settingStringValue);
	}

	private static bool UpdateConfigSetting(string settingKey, string settingValue)
	{
		// write out the value based on the key to the xml config file.
		// must check for an existing key prior to writing...
		try
		{
			bool foundNode = false;
			XmlDocument doc = new XmlDocument();
			doc.PreserveWhitespace = true;
			
			// setup the path...
			String configFilename = Application.ExecutablePath + ".config";

			// load the xml config file...
			doc.Load(configFilename);

			XmlNodeList appSettingsList = doc.GetElementsByTagName("appSettings");
			XmlNode appSettingsNode = appSettingsList.Item(0);

			XmlNodeList nodeList = doc.GetElementsByTagName("add");

			// searching to see if the "key" already exists...
			foreach (XmlNode node in nodeList)
			{
				if (node.Attributes[0].Value == settingKey)
				{
					foundNode = true;
					node.Attributes[1].Value = settingValue;
				}
			}

			// if the "key" is new...
			if (!foundNode)
			{
				// clone the first element to get all the correct settings...
				XmlNode newNode = nodeList.Item(0).Clone();

				// now change the clone to be the new "key" and "value"...
				newNode.Attributes[0].Value = settingKey;
				newNode.Attributes[1].Value = settingValue;

				// add the key to the document
				XmlNode insertedNode = appSettingsNode.AppendChild(newNode);

				// Preserves the whitespace formating
				//add a tab before the last entry...
				XmlSignificantWhitespace sigws = doc.CreateSignificantWhitespace("\t");
				appSettingsNode.InsertBefore(sigws, insertedNode);

				// add a CR/LF and tab after last entry...
				sigws = doc.CreateSignificantWhitespace("\r\n\t");
				appSettingsNode.InsertAfter(sigws, insertedNode);
			}

			// saves the changes to the xml config file...
			doc.Save(configFilename);
		}
		catch
		{
			return false;
		}

		return true;
	}

	private static void ExceptionHandling(Exception e, string key, string DefaultValue)
	{
		MessageBox.Show("Error converting the value in the config file.\n"+e.Message+"\nUsing the Default Value: " + DefaultValue + " for " + key);
	}
}
